/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.analysis.cli;

import cz.mzk.oai.metadataRepository.analysis.RecordPrintOptions;
import cz.mzk.oai.metadataRepository.analysis.cli.actions.Action;
import cz.mzk.oai.metadataRepository.analysis.cli.actions.AnalyzeEseAction;
import cz.mzk.oai.metadataRepository.analysis.cli.actions.AnalyzeMarcAction;
import cz.mzk.oai.metadataRepository.metadata.MetadataFormat;
import cz.mzk.oai.metadataRepository.repository.Repository;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.cli.ParseException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;

/**
 *
 * @author Martin Řehánek (rehan at mzk.cz)
 */
public class Main {

    private static final DefinedOptions DEFINED_OPTIONS = new DefinedOptions();

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            String[] testArgs = new String[]{
                //"-metadata_format", "marc21",
                //"-analysis_type", "datafield_856_u",
                "-metadata_format", "ese",
                "-analysis_type", "europeana:isShownBy",
                "-detailed_print",
                "-print_missing", "-print_multiple",// "-print_single",
                //"-print_identifiers",
                "-properties_file", "/home/rehan/NetBeansProjects/repositoryManager/local.properties",
                //"-collection", "schramVeduteBefore1800"
                //    "-collection", "schramVeduteAfter1800"
                //"-collection", "generalMzk03Before1800"
                "-collection", "generalMzk03After1800"
                        //"-collection", "generalMzk03Error1800"
            };
            args = testArgs;
            CommandLine commandLine = initCommandLine(args);
            Properties properties = loadProperties(getOptionValueIfPresent(commandLine, DEFINED_OPTIONS.PROPERTIES_FILE));
            Action action = determineAction(commandLine, properties);
            action.run();
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private static CommandLine initCommandLine(String[] args) throws ParseException {
        Options options = new Options();
        for (Option option : DEFINED_OPTIONS.getAllOptions()) {
            options.addOption(option);
        }
        CommandLineParser parser = new PosixParser();
        return parser.parse(options, args);
    }

    private static Properties loadProperties(String filename) throws IOException {
        Properties properties = new Properties();
        properties.load(new FileInputStream(filename));
        return properties;
    }

    private static Action determineAction(CommandLine cml, Properties properties) throws Exception {
        String metadataFormat = getOptionValueIfPresent(cml, DEFINED_OPTIONS.METADATA_FORMAT);
        MetadataFormat format = MetadataFormat.parseString(metadataFormat);
        return actionByFormat(format, properties, cml);
    }

    private static Action actionByFormat(MetadataFormat format, Properties properties, CommandLine cml) throws Exception {
        String analysisType = getOptionValueIfPresent(cml, DEFINED_OPTIONS.ANALYSIS_TYPE);
        String collection = getOptionValueIfPresent(cml, DEFINED_OPTIONS.COLLECTION);
        boolean printValues = getBooleanValue(cml, DEFINED_OPTIONS.DETAILED_PRINT);
        boolean printIdentifiers = getBooleanValue(cml, DEFINED_OPTIONS.PRINT_IDENTIFIERS);
        RecordPrintOptions options = loadRecordPrintOptions(cml);
        Repository rep = Repository.instanceOf(properties);
        switch (format) {
            case ese:
                return new AnalyzeEseAction(rep, analysisType, collection, printValues, printIdentifiers, options);
            case marc21:
                return new AnalyzeMarcAction(rep, analysisType, collection, printValues, printIdentifiers, options);
            default:
                throw new Exception("No analyzer for metadata format " + format);
        }
    }

    private static String getOptionValueIfPresent(CommandLine commandLine, Option option) {
        String opt = option.getOpt();
        if (commandLine.hasOption(opt)) {
            return commandLine.getOptionValue(opt);
        } else {
            return null;
        }
    }

    private static boolean getBooleanValue(CommandLine commandLine, Option option) {
        String opt = option.getOpt();
        if (commandLine.hasOption(opt)) {
            return true;
        } else {
            return false;
        }
    }

    private static RecordPrintOptions loadRecordPrintOptions(CommandLine cml) {
        boolean printMissing = getBooleanValue(cml, DEFINED_OPTIONS.PRINT_MISSING_VALUE);
        boolean printSingle = getBooleanValue(cml, DEFINED_OPTIONS.PRINT_SINGLE_VALUE);
        boolean printMultiple = getBooleanValue(cml, DEFINED_OPTIONS.PRINT_MULTIPLE_VALUES);
        return new RecordPrintOptions(printMissing, printSingle, printMultiple);
    }
}
